<template>
  <el-row type="flex" justify="center" :gutter="12">
    <el-col :span="18">
      <el-card shadow="never">
        <el-row slot="header" type="flex" justify="around">
          <el-col :span="12">
            <el-select
              @change="projectSelect"
              placeholder="请选择项目"
              :value="currentProjectId">
              <el-option
                v-for="project in projectList"
                :key="project.id"
                :label="project.name"
                :value="project.id">
                <span style="float: left">{{ project.name }}</span>
                <span style="float: right; color: #8492a6; font-size: 13px">{{ project.id }}</span>
              </el-option>
            </el-select>
          </el-col>
          <el-col>
            <div style="float: right">
              <el-popover placement="left-start" v-model="addFormVisible">
                <el-button slot="reference" icon="el-icon-plus" title="新增顶级待办任务" :disabled="currentProjectId === undefined" circle></el-button>
                <TodoForm @onSubmit="closeForm" style="max-width: 600px;" :subject-id="currentProjectId"></TodoForm>
              </el-popover>
              <el-button
                icon="el-icon-refresh"
                title="刷新表格数据"
                :disabled="currentProjectId === undefined"
                @click="refreshTable"
                :loading="tableLoading"
                circle></el-button>
            </div>
          </el-col>
        </el-row>
        <el-table
          slot="default"
          max-height="2160"
          ref="todoTable"
          id="todoTable"
          v-loading.fullscreen="tableLoading"
          highlight-current-row
          :data="tableData.todo"
          lazy
          :load="loadSubTodo"
          :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
          row-key="id">
          <el-table-column
            label="ID"
            header-align="center"
            align="center"
            sortable
            prop="id">
          </el-table-column>
          <el-table-column
            label="优先级"
            header-align="center"
            align="center"
            sortable
            prop="level">
            <template slot-scope="scope">
              <el-tag :type="todoEnumMap.TodoLevelEnum[scope.row.level].type">
                {{ todoEnumMap.TodoLevelEnum[scope.row.level].text }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="任务名称"
            header-align="center"
            align="center"
            sortable
            show-tooltip-when-overflow
            prop="name">
            <!--                <template slot-scope="scope">-->
            <!--                  <el-popover trigger="click" :content="scope.row.name">-->
            <!--                    <div title="点击查看项目名称" slot="reference">{{ compressText(scope.row.name) }}</div>-->
            <!--                  </el-popover>-->
            <!--                </template>-->
          </el-table-column>
          <el-table-column
            label="状态"
            header-align="center"
            align="center"
            sortable
            prop="status">
            <template slot-scope="scope">
              <el-tag :type="todoEnumMap.TodoStatusEnum[scope.row.status].type">
                {{ todoEnumMap.TodoStatusEnum[scope.row.status].text }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="类型"
            header-align="center"
            align="center"
            sortable
            prop="type">
            <template slot-scope="scope">
              <el-tag :type="todoEnumMap.TodoTypeEnum[scope.row.type].type">
                {{ todoEnumMap.TodoTypeEnum[scope.row.type].text }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            label="截止"
            header-align="center"
            align="center"
            sortable
            show-tooltip-when-overflow
            prop="deadLine">
            <template slot-scope="scope">
              <span>{{ scope.row.deadLine.substr(5, 14) }}</span>
              <!--                  <el-popover-->
              <!--                    placement="top-start"-->
              <!--                    width="100"-->
              <!--                    trigger="hover"-->
              <!--                    :content="scope.row.deadLine">-->
              <!--                    <span slot="reference">{{ scope.row.deadLine.substr(5, 5) }}</span>-->
              <!--                  </el-popover>-->
            </template>
          </el-table-column>
          <el-table-column
            label="创建日期"
            header-align="center"
            align="center"
            sortable
            v-if="false"
            show-tooltip-when-overflow
            prop="createTime">
            <template slot-scope="scope">
              <span>{{ scope.row.createTime.substr(5, 14) }}</span>
              <!--                  <el-popover-->
              <!--                    placement="top-start"-->
              <!--                    width="100"-->
              <!--                    trigger="hover"-->
              <!--                    :content="scope.row.createTime">-->
              <!--                    <span slot="reference">{{ scope.row.createTime.substr(5, 11) }}</span>-->
              <!--                  </el-popover>-->
            </template>
          </el-table-column>
          <el-table-column
            label="耗时"
            header-align="center"
            align="center"
            sortable
            prop="cost">
            <template slot-scope="scope">
              <span>{{ scope.row.cost + 'h' }}</span>
            </template>
          </el-table-column>
          <el-table-column
            label="操作"
            header-align="center"
            width="250"
            align="left">
            <template slot-scope="scope">
              <el-popover trigger="click" width="500">
                <el-button slot="reference" size="small" icon="el-icon-search" title="查看任务详情" circle></el-button>
                <div style="margin: 10px 10px">
                  <div>
                    <span>任务编号：</span>
                    {{ scope.row.id }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>任务名称：</span>
                    {{ scope.row.name }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>优先级别：</span>
                    {{ scope.row.level }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>任务状态：</span>
                    {{ scope.row.status }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>预计耗时：</span>
                    {{ scope.row.cost }}小时
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>任务描述：</span>
                    {{ scope.row.description ? scope.row.description : '无' }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>创建时间：</span>
                    {{ scope.row.createTime }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>修改时间：</span>
                    {{ scope.row.updateTime }}
                  </div>
                  <el-divider></el-divider>
                  <div>
                    <span>任务结果：</span>
                    {{ scope.row.result ? scope.row.result : '无' }}
                  </div>
                </div>
              </el-popover>
              <el-popover placement="left-start" v-model="updateVisibles[scope.$index]">
                <el-button slot="reference" size="small" icon="el-icon-edit-outline" title="编辑任务" type="primary" circle></el-button>
                <TodoForm @onSubmit="closeUpdateForm" @onCancel="cancelPopover(updateVisibles, scope.row, scope.$index)" :top-todos="tableData.todo" :current-project-data="scope.row" update-mode style="max-width: 600px;" :subject-id="currentProjectId"></TodoForm>
              </el-popover>
              <el-popover v-model="completeVisibles[scope.$index]" @show="initResult(scope.row.result)">
                <el-button slot="reference" size="small" icon="el-icon-check" title="完成任务" type="success" circle></el-button>
                <el-input type="textarea" v-model="todoResult" placeholder="输入结果"></el-input>
                <el-button style="width: 100%; margin-top: 10px" @click="completedTodo(scope.row.id, scope.row.fatherId, completeVisibles, scope)">保存</el-button>
              </el-popover>
              <el-button size="small" icon="el-icon-delete" title="删除任务" type="danger" @click="deleteTodo(scope.row.id, scope.row.fatherId)" circle></el-button>
              <el-popover placement="left-start" v-model="delVisibles[scope.$index]">
                <el-button slot="reference" size="small" icon="el-icon-plus" v-if="!scope.row.fatherId" title="新增子待办任务" circle></el-button>
                <TodoForm @onSubmit="closeSubTodoForm" @onCancel="cancelPopover(delVisibles, scope.row, scope.$index)" :top-todos="tableData.todo" father-todo-mode :current-father-id="scope.row.id" style="max-width: 600px;" :subject-id="currentProjectId"></TodoForm>
              </el-popover>
            </template>
          </el-table-column>
        </el-table>
      </el-card>
    </el-col>
  </el-row>
</template>

<script>
import Header from '@/components/Header'
import Footer from '@/components/Footer'
import {getTodos, updateTodo} from '@/api/todo'
import {getProjects} from '@/api/project'
import TodoForm from '@/components/TodoForm'
import todoEnum from '@/utils/todoEnum'
export default {
  name: 'todo',
  components: {
    Header,
    Footer,
    TodoForm
  },
  data () {
    return {
      tableData: {
        todo: []
      },
      projectList: [],
      currentProjectId: undefined,
      tableLoading: false,
      addFormVisible: false,
      subFormVisible: false,
      maps: new Map(),
      delVisibles: [],
      updateVisibles: [],
      completeVisibles: [],
      todoResult: ''
    }
  },
  created () {
    this.$store.dispatch('SetCurrentMenu', '待办任务')
  },
  mounted () {
    this.currentProjectId = this.$store.getters.currentProject
    this.loadProjectList()
  },
  methods: {
    projectSelect (selectValue) {
      this.tableLoading = true
      this.currentProjectId = selectValue
      this.$store.commit('SET_CURRENT_PROJECT', selectValue)
      setTimeout(() => {
        this.tableLoading = false
      }, 300)
    },
    loadProjectList () {
      getProjects().then(res => {
        this.projectList = res.data
      }).catch(res => {
        this.$notify.error({
          title: '加载项目列表',
          message: res.msg
        })
      })
    },
    loadProjectTodo () {
      getTodos(this.currentProjectId).then(res => {
        this.$set(this.tableData, 'todo', res.data)
        for (let todoElement of this.tableData.todo) {
          todoElement['hasChildren'] = true
        }
      }).catch(error => {
        this.$notify.error({
          title: '加载项目任务失败',
          message: error.message
        })
      })
    },
    clone (obj) {
      // 区分是数组还是对象，创建空的数组或对象
      const o = Object.prototype.toString.call(obj).slice(8, -1) === 'Array' ? [] : {}
      // 判断是对象，就进行循环复制
      if (typeof obj === 'object' && obj != null) {
        for (const k in obj) {
          // 如果属性对应的值为对象，则递归复制
          if (typeof obj[k] === 'object' && obj[k] != null) {
            // eslint-disable-next-line no-undef
            o[k] = this.clone(obj[k])
          } else {
            o[k] = obj[k]
          }
        }
      } else {
        // 不为对象，直接把值返回
        return obj
      }
      return o
    },
    compressText (text, displayLength = 8) {
      if (!text || (text + '').length <= displayLength) {
        return text
      }
      return text.substr(0, displayLength) + '...'
    },
    refreshTable () {
      this.tableLoading = true
      setTimeout(() => {
        this.loadProjectTodo()
        this.tableLoading = false
      }, 300)
    },
    loadSubTodo (tree, treeNode, resolve) {
      this.maps.set(tree.id, { tree, treeNode, resolve })
      getTodos(this.currentProjectId, tree.id).then(res => {
        let subTodos = res.data
        if (subTodos.length < 1) {
          this.$notify.warning('当前待办任务无子任务')
        }
        resolve(subTodos)
      }).catch(error => {
        this.$notify.error(error.message)
      })
    },
    // 重新触发树形表格的loadTree函数(因项目中需要多次触发loadTree方法，故封装成一个方法)
    refreshLoadTree (parentId) {
      // 根据父级id取出对应节点数据
      const { tree, treeNode, resolve } = this.maps.get(parentId)
      this.$set(this.$refs.todoTable.store.states.lazyTreeNodeMap, parentId, [])
      if (tree) {
        this.loadSubTodo(tree, treeNode, resolve)
      }
    },
    closeForm () {
      this.addFormVisible = false
      this.refreshTable()
    },
    closeSubTodoForm (fatherId) {
      this.subFormVisible = false
      if (this.maps.get(fatherId)) {
        this.refreshLoadTree(fatherId)
      }
    },
    completedTodo (todoId, fatherId, visibles, scope) {
      updateTodo({
        id: todoId,
        status: '10',
        result: this.todoResult
      }).then(() => {
        this.$notify.success('修改成功')
        this.todoResult = ''
        this.cancelPopover(visibles, scope.row, scope.$index)
        this.refreshTable()
        this.refreshLoadTree(fatherId)
      })
    },
    deleteTodo (todoId, fatherId) {
      updateTodo({
        id: todoId,
        enable: '20'
      }).then(() => {
        this.$notify.success('删除成功')
        this.refreshLoadTree(fatherId)
        this.refreshTable()
      })
    },
    cancelPopover (array, row, index) {
      this.$set(array, index, false)
    },
    closeUpdateForm (fatherId) {
      if (fatherId) {
        this.refreshLoadTree(fatherId)
      }
      this.refreshTable()
    },
    initResult (result) {
      this.todoResult = result
    }
  },
  watch: {
    currentProjectId: {
      deep: true,
      handler: function (newId, oldId) {
        this.currentProjectId = newId
        this.loadProjectTodo()
      }
    }
  },
  computed: {
    todoEnumMap () {
      return todoEnum
    }
  }
}
</script>

<style lang="scss" scoped>
.table-row {
  margin-top: 30px;
}
.el-card {
  border: 1px solid #d9dce2;
}
</style>
